package com.example.rssreader.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.rssreader.entity.Article;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 文章数据访问层接口
 * 继承MyBatis Plus的BaseMapper，提供基础的CRUD操作
 * 
 * @author RSS Reader Team
 * @version 1.0.0
 * @since 2024-01-01
 */
@Mapper
public interface ArticleMapper extends BaseMapper<Article> {

    /**
     * 分页查询文章列表
     * 按发布时间倒序排列
     * 
     * @param page   分页参数
     * @param feedId RSS源ID，可选参数
     * @param isRead 是否已读，可选参数
     * @return 分页结果
     */
    @Select("<script>" +
            "SELECT a.*, f.title as feed_title, f.url as feed_url " +
            "FROM article a " +
            "LEFT JOIN rss_feed f ON a.feed_id = f.id " +
            "WHERE a.deleted = 0 " +
            "<if test='feedId != null'>AND a.feed_id = #{feedId}</if> " +
            "<if test='isRead != null'>AND a.is_read = #{isRead}</if> " +
            "ORDER BY a.published_at DESC" +
            "</script>")
    IPage<Article> selectArticlePage(Page<Article> page, 
                                   @Param("feedId") Long feedId, 
                                   @Param("isRead") Boolean isRead);

    /**
     * 根据GUID查询文章
     * 用于检查文章是否已存在
     * 
     * @param guid   文章GUID
     * @param feedId RSS源ID
     * @return 文章实体，如果不存在则返回null
     */
    @Select("SELECT * FROM article WHERE guid = #{guid} AND feed_id = #{feedId} AND deleted = 0 LIMIT 1")
    Article selectByGuid(@Param("guid") String guid, @Param("feedId") Long feedId);

    /**
     * 根据关键词搜索文章
     * 在标题、描述和内容中进行模糊搜索
     * 
     * @param page    分页参数
     * @param keyword 搜索关键词
     * @param feedId  RSS源ID，可选参数
     * @return 分页结果
     */
    @Select("<script>" +
            "SELECT a.*, f.title as feed_title, f.url as feed_url " +
            "FROM article a " +
            "LEFT JOIN rss_feed f ON a.feed_id = f.id " +
            "WHERE a.deleted = 0 " +
            "AND (a.title LIKE CONCAT('%', #{keyword}, '%') " +
            "OR a.description LIKE CONCAT('%', #{keyword}, '%') " +
            "OR a.content LIKE CONCAT('%', #{keyword}, '%')) " +
            "<if test='feedId != null'>AND a.feed_id = #{feedId}</if> " +
            "ORDER BY a.published_at DESC" +
            "</script>")
    IPage<Article> searchArticles(Page<Article> page, 
                                @Param("keyword") String keyword, 
                                @Param("feedId") Long feedId);

    /**
     * 统计未读文章数量
     * 
     * @param feedId RSS源ID，可选参数
     * @return 未读文章数量
     */
    @Select("<script>" +
            "SELECT COUNT(*) FROM article " +
            "WHERE deleted = 0 AND is_read = 0 " +
            "<if test='feedId != null'>AND feed_id = #{feedId}</if>" +
            "</script>")
    Long countUnreadArticles(@Param("feedId") Long feedId);

    /**
     * 批量标记文章为已读
     * 
     * @param articleIds 文章ID列表
     * @return 更新的记录数
     */
    @Update("<script>" +
            "UPDATE article SET is_read = 1, updated_at = NOW() " +
            "WHERE id IN " +
            "<foreach collection='articleIds' item='id' open='(' separator=',' close=')'>" +
            "#{id}" +
            "</foreach>" +
            "</script>")
    int batchMarkAsRead(@Param("articleIds") List<Long> articleIds);

    /**
     * 标记RSS源下所有文章为已读
     * 
     * @param feedId RSS源ID
     * @return 更新的记录数
     */
    @Update("UPDATE article SET is_read = 1, updated_at = NOW() " +
            "WHERE feed_id = #{feedId} AND is_read = 0 AND deleted = 0")
    int markFeedArticlesAsRead(@Param("feedId") Long feedId);

    /**
     * 删除指定时间之前的文章
     * 用于清理旧文章
     * 
     * @param beforeTime 时间阈值
     * @return 删除的记录数
     */
    @Update("UPDATE article SET deleted = 1, updated_at = NOW() " +
            "WHERE published_at < #{beforeTime} AND deleted = 0")
    int deleteArticlesBefore(@Param("beforeTime") LocalDateTime beforeTime);

    /**
     * 获取最新文章
     * 
     * @param limit 限制数量
     * @return 文章列表
     */
    @Select("SELECT a.*, f.title as feed_title, f.url as feed_url " +
            "FROM article a " +
            "LEFT JOIN rss_feed f ON a.feed_id = f.id " +
            "WHERE a.deleted = 0 " +
            "ORDER BY a.published_at DESC " +
            "LIMIT #{limit}")
    List<Article> selectLatestArticles(@Param("limit") Integer limit);

    /**
     * 统计RSS源的文章总数
     * 
     * @param feedId RSS源ID
     * @return 文章总数
     */
    @Select("SELECT COUNT(*) FROM article WHERE feed_id = #{feedId} AND deleted = 0")
    Long countArticlesByFeed(@Param("feedId") Long feedId);
}